package com.benew.ntt.player.audiofocus

import android.content.Context
import android.media.AudioAttributes
import android.media.AudioFocusRequest
import android.media.AudioManager
import android.os.Build
import com.google.android.exoplayer2.util.Log

class AudioFocusChangeListener(context: Context) {

    private val mAudioManger: AudioManager =
        context.applicationContext.getSystemService(Context.AUDIO_SERVICE) as AudioManager
    private var mAudioFocusListener: AudioFocusListener? = null
    private var playbackDelayed = false
    private var resumeOnFocusGain = false
    private val focusLock = Any()
    private var requestFocus: AudioFocusRequest? = null


    fun requestAudioFocus(): Boolean {
        if (Build.VERSION.SDK_INT > Build.VERSION_CODES.O) {
            requestFocus = AudioFocusRequest.Builder(AudioManager.AUDIOFOCUS_GAIN).run {
                setAudioAttributes(AudioAttributes.Builder().run {
                    setUsage(AudioAttributes.USAGE_MEDIA)
                    setContentType(AudioAttributes.CONTENT_TYPE_MUSIC)
                    build()
                })
                setAcceptsDelayedFocusGain(true)
                setOnAudioFocusChangeListener(afChangeListener)
                build()
            }
            requestFocus?.run {
                val result = mAudioManger.requestAudioFocus(this)
                synchronized(focusLock) {
                    return when (result) {
                        AudioManager.AUDIOFOCUS_REQUEST_GRANTED -> true
                        AudioManager.AUDIOFOCUS_REQUEST_DELAYED -> {
                            Log.d(TAG, "播放延迟了")
                            playbackDelayed = true
                            false
                        }
                        else -> false
                    }
                }
            }
            return false
        } else {
            return mAudioManger.requestAudioFocus(
                afChangeListener,
                AudioManager.STREAM_MUSIC,
                AudioManager.AUDIOFOCUS_GAIN
            ) == AudioManager.AUDIOFOCUS_REQUEST_GRANTED
        }
    }


    fun abandonAudioFocus() {
        requestFocus?.run {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                mAudioManger.abandonAudioFocusRequest(this)
            } else {
                mAudioManger.abandonAudioFocus(null)
            }
        }
    }

    fun setOnAudioFocusListener(audioFocusListener: AudioFocusListener) {
        mAudioFocusListener = audioFocusListener
    }

    private val afChangeListener = AudioManager.OnAudioFocusChangeListener { focusChange ->
        when (focusChange) {
            //重新获取音频焦点
            AudioManager.AUDIOFOCUS_GAIN -> {
                if (playbackDelayed || resumeOnFocusGain) {
                    synchronized(focusLock) {
                        playbackDelayed = false
                        resumeOnFocusGain = false
                    }
                    Log.d(TAG, "重新获取音频焦点")
                    mAudioFocusListener?.audioFocusGain()
                }
            }
            //永久丢失音频焦点，被其他播放源抢占
            AudioManager.AUDIOFOCUS_LOSS -> {
                synchronized(focusLock) {
                    resumeOnFocusGain = false
                    playbackDelayed = false
                }
                Log.d(TAG, "永久丢失音频焦点，被其他播放源抢占")
                mAudioFocusListener?.audioFocusLoss()
            }
            //短暂丢失音频焦点，电话视频聊天等
            AudioManager.AUDIOFOCUS_LOSS_TRANSIENT -> {
                synchronized(focusLock) {
                    resumeOnFocusGain = true
                    playbackDelayed = false
                }
                Log.d(TAG, "短暂丢失音频焦点，电话视频聊天等")
                mAudioFocusListener?.audioFocusLossTransient()
            }
            //瞬间丢失音频焦点，通知，语音提示等
            AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK -> {
                Log.d(TAG, "瞬间丢失音频焦点，通知，语音提")
                mAudioFocusListener?.audioFocusLossTransientCanDuck()
            }

        }
    }

    private companion object {
        const val TAG = "AudioFocus"
    }
}